package com.example.zhilierp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zhilierp.entity.Dept;
import com.example.zhilierp.entity.User;
import com.example.zhilierp.exception.BusinessException;
import com.example.zhilierp.mapper.DeptMapper;
import com.example.zhilierp.mapper.UserMapper;
import com.example.zhilierp.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门服务实现类
 * 实现部门相关的业务逻辑
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<Dept> getDeptTree() {
        // 查询所有部门
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getDeleted, 0)
                   .orderByAsc(Dept::getSort);
        List<Dept> depts = list(queryWrapper);
        
        // 构建部门树
        return buildDeptTree(depts, 0L);
    }

    @Override
    public boolean checkDeptNameUnique(String deptName, Long deptId, Long parentId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getDeptName, deptName)
                   .eq(Dept::getParentId, parentId)
                   .eq(Dept::getDeleted, 0);
        // 如果是编辑操作，排除当前部门
        if (deptId != null) {
            queryWrapper.ne(Dept::getId, deptId);
        }
        Dept dept = getOne(queryWrapper);
        return dept == null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertDept(Dept dept) {
        // 检查部门名称是否唯一
        if (!checkDeptNameUnique(dept.getDeptName(), null, dept.getParentId())) {
            throw new BusinessException("部门名称已存在");
        }
        // 保存部门信息
        return save(dept);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDept(Dept dept) {
        // 检查部门名称是否唯一
        if (!checkDeptNameUnique(dept.getDeptName(), dept.getId(), dept.getParentId())) {
            throw new BusinessException("部门名称已存在");
        }
        // 更新部门信息
        return updateById(dept);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDept(Long deptId) {
        // 检查部门是否有子部门
        if (hasChildDept(deptId)) {
            throw new BusinessException("该部门下存在子部门，不能删除");
        }
        // 检查部门是否有用户
        if (hasUser(deptId)) {
            throw new BusinessException("该部门下存在用户，不能删除");
        }
        // 删除部门
        return removeById(deptId);
    }

    @Override
    public boolean hasChildDept(Long deptId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getParentId, deptId)
                   .eq(Dept::getDeleted, 0);
        return count(queryWrapper) > 0;
    }

    @Override
    public boolean hasUser(Long deptId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDeptId, deptId)
                   .eq(User::getDeleted, 0);
        return userMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 构建部门树
     * @param depts 部门列表
     * @param parentId 父部门ID
     * @return 部门树
     */
    private List<Dept> buildDeptTree(List<Dept> depts, Long parentId) {
        List<Dept> tree = new ArrayList<>();
        
        // 找到所有父部门ID等于parentId的部门
        List<Dept> parentDepts = depts.stream()
                .filter(d -> Objects.equals(d.getParentId(), parentId))
                .collect(Collectors.toList());
        
        // 对每个父部门，递归查找其子部门
        for (Dept dept : parentDepts) {
            // 递归查找子部门
            List<Dept> children = buildDeptTree(depts, dept.getId());
            // 设置子部门
            // 注意：这里需要扩展Dept类，添加children字段
            // 由于当前Dept类没有children字段，这里只是构建了树结构，实际使用时需要处理
            tree.add(dept);
        }
        
        return tree;
    }
}